﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EasyHook;
using System.Runtime.InteropServices;

namespace MalMonInject
{
    public class ProcActivities:ActivityMonitor
    {
        LocalHook CreateProcessHook;
        LocalHook ExitProcessHook;
        LocalHook TerminateProcessHook;
        LocalHook CreateThreadHook;
        LocalHook TerminateThreadHook;

        public ProcActivities(MalMonInject Inject) : base(Inject) { }
        public override void InstallHook()
        {
            CreateProcessHook = LocalHook.Create(
                        LocalHook.GetProcAddress("kernel32.dll", "CreateProcessW"),
                        new DCreateProcessW(CreateProcessW_Hooked),
                        this.Injector);
            CreateProcessHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });

            ExitProcessHook = LocalHook.Create(
                        LocalHook.GetProcAddress("kernel32.dll", "ExitProcess"),
                        new DExitProcess(ExitProcess_Hooked),
                        this.Injector);
            ExitProcessHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });

            TerminateProcessHook = LocalHook.Create(
                        LocalHook.GetProcAddress("kernel32.dll", "TerminateProcess"),
                        new DTerminateProcess(TerminateProcess_Hooked),
                        this.Injector);
            TerminateProcessHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });

            CreateThreadHook = LocalHook.Create(
                        LocalHook.GetProcAddress("kernel32.dll", "CreateThread"),
                        new DCreateThread(CreateThread_Hooked),
                        this.Injector);
            CreateThreadHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });

            TerminateThreadHook = LocalHook.Create(
                       LocalHook.GetProcAddress("kernel32.dll", "TerminateThread"),
                       new DTerminateThread(TerminateThread_Hooked),
                       this.Injector);
            TerminateThreadHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
        }

        /*----code generated by script CodeGenerator.py----*/
        /*----CreateProcessW----*/
        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct STARTUPINFOW
        {

            /// DWORD->unsigned int
            public uint cb;

            /// LPWSTR->WCHAR*
            [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
            public string lpReserved;

            /// LPWSTR->WCHAR*
            [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
            public string lpDesktop;

            /// LPWSTR->WCHAR*
            [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
            public string lpTitle;

            /// DWORD->unsigned int
            public uint dwX;

            /// DWORD->unsigned int
            public uint dwY;

            /// DWORD->unsigned int
            public uint dwXSize;

            /// DWORD->unsigned int
            public uint dwYSize;

            /// DWORD->unsigned int
            public uint dwXCountChars;

            /// DWORD->unsigned int
            public uint dwYCountChars;

            /// DWORD->unsigned int
            public uint dwFillAttribute;

            /// DWORD->unsigned int
            public uint dwFlags;

            /// WORD->unsigned short
            public ushort wShowWindow;

            /// WORD->unsigned short
            public ushort cbReserved2;

            /// LPBYTE->BYTE*
            public System.IntPtr lpReserved2;

            /// HANDLE->void*
            public System.IntPtr hStdInput;

            /// HANDLE->void*
            public System.IntPtr hStdOutput;

            /// HANDLE->void*
            public System.IntPtr hStdError;
        }
        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct PROCESS_INFORMATION
        {

            /// HANDLE->void*
            public System.IntPtr hProcess;

            /// HANDLE->void*
            public System.IntPtr hThread;

            /// DWORD->unsigned int
            public uint dwProcessId;

            /// DWORD->unsigned int
            public uint dwThreadId;
        }

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        delegate bool DCreateProcessW([MarshalAsAttribute(UnmanagedType.LPWStr)] string lpApplicationName, IntPtr lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, [MarshalAsAttribute(UnmanagedType.Bool)] bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, [MarshalAsAttribute(UnmanagedType.LPWStr)] string lpCurrentDirectory, ref STARTUPINFOW lpStartupInfo, [OutAttribute()] out PROCESS_INFORMATION lpProcessInformation);
        [DllImportAttribute("kernel32.dll", EntryPoint = "CreateProcessW")]
        [return: MarshalAsAttribute(UnmanagedType.Bool)]
        static extern bool CreateProcessW([InAttribute()] [MarshalAsAttribute(UnmanagedType.LPWStr)] string lpApplicationName, IntPtr lpCommandLine, [InAttribute()] IntPtr lpProcessAttributes, [InAttribute()] IntPtr lpThreadAttributes, [MarshalAsAttribute(UnmanagedType.Bool)] bool bInheritHandles, uint dwCreationFlags, [InAttribute()] IntPtr lpEnvironment, [InAttribute()] [MarshalAsAttribute(UnmanagedType.LPWStr)] string lpCurrentDirectory, [InAttribute()] ref STARTUPINFOW lpStartupInfo, [OutAttribute()] out PROCESS_INFORMATION lpProcessInformation);

        static bool CreateProcessW_Hooked([MarshalAsAttribute(UnmanagedType.LPWStr)] string lpApplicationName, IntPtr lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, [MarshalAsAttribute(UnmanagedType.Bool)] bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, [MarshalAsAttribute(UnmanagedType.LPWStr)] string lpCurrentDirectory, ref STARTUPINFOW lpStartupInfo, [OutAttribute()] out PROCESS_INFORMATION lpProcessInformation)
        {
            try
            {
                MalMonInject This = (MalMonInject)HookRuntimeInfo.Callback;

                lock (This.Queue)
                {
                    //Time + Pid + Tid + Api + Content
                    This.Queue.Push(ActivityMonitor.FormatMessage(DateTime.Now, "CreateProcessW", Marshal.PtrToStringUni(lpCommandLine)));
                }
            }
            catch
            {
            }

            // call original API...
            return CreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, ref lpStartupInfo, out lpProcessInformation);
        }

        /*----code generated by script CodeGenerator.py----*/
        /*----ExitProcess----*/
        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        delegate void DExitProcess(uint uExitCode);
        [DllImportAttribute("kernel32.dll", EntryPoint = "ExitProcess")]
        static extern void ExitProcess(uint uExitCode);

        static void ExitProcess_Hooked(uint uExitCode)
        {
            try
            {
                MalMonInject This = (MalMonInject)HookRuntimeInfo.Callback;

                lock (This.Queue)
                {
                    //Time + Pid + Tid + Api + Content
                    This.Queue.Push(ActivityMonitor.FormatMessage(DateTime.Now, "ExitProcess", ""));
                }
            }
            catch
            {
            }

            // call original API...
            ExitProcess(uExitCode);
        }
        /*----code generated by script CodeGenerator.py----*/
        /*----TerminateProcess----*/
        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        delegate bool DTerminateProcess(IntPtr hProcess, uint uExitCode);
        [DllImportAttribute("kernel32.dll", EntryPoint = "TerminateProcess")]
        [return: MarshalAsAttribute(UnmanagedType.Bool)]
        static extern bool TerminateProcess([InAttribute()] IntPtr hProcess, uint uExitCode);

        static bool TerminateProcess_Hooked(IntPtr hProcess, uint uExitCode)
        {
            try
            {
                MalMonInject This = (MalMonInject)HookRuntimeInfo.Callback;

                lock (This.Queue)
                {
                    //Time + Pid + Tid + Api + Content
                    This.Queue.Push(ActivityMonitor.FormatMessage(DateTime.Now, "TerminateProcess", ""));
                }
            }
            catch
            {
            }

            // call original API...
            return TerminateProcess(hProcess, uExitCode);
        }
        /*----code generated by script CodeGenerator.py----*/
        /*----CreateThread----*/
        public delegate uint PTHREAD_START_ROUTINE(System.IntPtr lpThreadParameter);

        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct SECURITY_ATTRIBUTES
        {

            /// DWORD->unsigned int
            public uint nLength;

            /// LPVOID->void*
            public System.IntPtr lpSecurityDescriptor;

            /// BOOL->int
            [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
            public bool bInheritHandle;
        }

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        delegate IntPtr DCreateThread(IntPtr lpThreadAttributes, uint dwStackSize, PTHREAD_START_ROUTINE lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
        [DllImportAttribute("kernel32.dll", EntryPoint = "CreateThread")]
        static extern IntPtr CreateThread([InAttribute()] IntPtr lpThreadAttributes, uint dwStackSize, PTHREAD_START_ROUTINE lpStartAddress, [InAttribute()] IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);

        static IntPtr CreateThread_Hooked(IntPtr lpThreadAttributes, uint dwStackSize, PTHREAD_START_ROUTINE lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId)
        {
            try
            {
                MalMonInject This = (MalMonInject)HookRuntimeInfo.Callback;

                lock (This.Queue)
                {
                    //Time + Pid + Tid + Api + Content
                    This.Queue.Push(ActivityMonitor.FormatMessage(DateTime.Now, "CreateThread", ""));
                }
            }
            catch
            {
            }

            return CreateThread(lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId);
        }
        /*----code generated by script CodeGenerator.py----*/
        /*----TerminateThread----*/
        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        delegate bool DTerminateThread(IntPtr hThread, uint dwExitCode);
        [DllImportAttribute("kernel32.dll", EntryPoint = "TerminateThread")]
        [return: MarshalAsAttribute(UnmanagedType.Bool)]
        static extern bool TerminateThread([InAttribute()] IntPtr hThread, uint dwExitCode);

        static bool TerminateThread_Hooked(IntPtr hThread, uint dwExitCode)
        {
            try
            {
                MalMonInject This = (MalMonInject)HookRuntimeInfo.Callback;

                lock (This.Queue)
                {
                    //Time + Pid + Tid + Api + Content
                    This.Queue.Push(ActivityMonitor.FormatMessage(DateTime.Now, "TerminateThread", "TheadId:"));
                }
            }
            catch
            {
            }

            return TerminateProcess(hThread, dwExitCode);
        }

    }
}
